﻿/**
 * Licensed to Open-Ones Group under one or more contributor license
 * agreements. See the NOTICE file distributed with this work
 * for additional information regarding copyright ownership.
 * Open-Ones Group licenses this file to you under the Apache License,
 * Version 2.0 (the "License"); you may not use this file
 * except in compliance with the License. You may obtain a
 * copy of the License at:
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on
 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied. See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
namespace IPresenter
{
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Threading;
    using System.Windows.Forms;

    /// <summary>
    /// This class provide functions to control Open Office
    /// </summary>
    public static class OpenOfficeSupport
    {
        /// <summary>
        /// Slide number that user would like to go
        /// </summary>
        private static int SlideNumberGoTo;

        /// <summary>
        /// Name file of open office whose is controlling
        /// </summary>
        private static string FileNameOpenOffice;

        /// <summary>
        /// List file powerpoint is openning by open office
        /// </summary>
        private static List<OpenOffice> LFOpenOffice;

        /// <summary>
        /// Handle of presentation whose is controlling
        /// </summary>
        private static int HAPresentation;

        /// <summary>
        /// Gets or sets slide number you would like to go
        /// </summary>
        public static int SlideNumber
        {
            get { return OpenOfficeSupport.SlideNumberGoTo; }
            set { OpenOfficeSupport.SlideNumberGoTo = value; }
        }
       
        /// <summary>
        /// Gets or sets file name
        /// </summary>
        public static string FileName
        {
            get { return FileNameOpenOffice; }
            set { FileNameOpenOffice = value; }
        }
     
        /// <summary>
        /// Gets or sets list file powerpoint are being opened
        /// </summary>
        public static List<OpenOffice> ListFileOpenOffice
        {
            get { return OpenOfficeSupport.LFOpenOffice; }
            set { OpenOfficeSupport.LFOpenOffice = value; }
        } 

        /// <summary>
        /// Gets or sets handle active presentation
        /// </summary>
        public static int HandleActivePresentation
        {
            get { return OpenOfficeSupport.HAPresentation; }
            set { OpenOfficeSupport.HAPresentation = value; }
        }

        /// <summary>
        /// Get list file open office is running
        /// </summary>
        /// <returns>List of file</returns>
        public static List<OpenOffice> GetListOfOpenOffice()
        {
            ListFileOpenOffice = new List<OpenOffice>();
            int intHWnd = ApiFunction.FindWindow("SysListView32", IntPtr.Zero);
            int intHwndChild = ApiFunction.FindWindowEx(intHWnd, IntPtr.Zero, "SALFRAME", IntPtr.Zero);
            while (intHwndChild != 0)
            {
                int intSizeWindowText = 0;
                OpenOffice ooData = new OpenOffice();
                StringBuilder strBuilderTam = new StringBuilder(255);
                intSizeWindowText = ApiFunction.GetWindowText(intHwndChild, strBuilderTam, 255);
                if (intSizeWindowText > 0)
                {
                    ooData = new OpenOffice(intHwndChild, strBuilderTam.ToString());
                    ListFileOpenOffice.Add(ooData);
                }

                intHwndChild = ApiFunction.FindWindowEx(intHWnd, intHwndChild, "SALFRAME", IntPtr.Zero);
            }

            return ListFileOpenOffice;
        }

        /// <summary>
        /// Determine which presentation will being chosen
        /// </summary>
        /// <param name="fileName">Name of presentation</param>
        /// <returns>
        /// true: if presentation exist
        /// false: if presentation is not exist
        /// </returns>
        public static bool DeterminePresentation(string fileName)
        {
            GetListOfOpenOffice();
            foreach (OpenOffice ooTemp in ListFileOpenOffice)
            {
                if (ooTemp.NameFile == fileName)
                {
                    HandleActivePresentation = ooTemp.Handle;
                    return true;
                }
            }

            return false;
        }

        /// <summary>
        /// Determine which presentation is being activated
        /// </summary>
        /// <returns>
        /// true: if presentation is activated
        /// false: contrary.
        /// </returns>
        public static bool DeterminePresentation()
        {
            int intHWnd = 0;
            int intClasNameSize = 0;
            intHWnd = ApiFunction.GetForegroundWindow();
            StringBuilder strBuilderClassName = new StringBuilder(255);
            intClasNameSize = ApiFunction.GetClassName(intHWnd, strBuilderClassName, 255);
            if (intClasNameSize > 0)
            {
                if (strBuilderClassName.ToString().Equals("SALTMPSUBFRAME") == true)
                {
                    HandleActivePresentation = intHWnd;
                    return true;
                }

                if (strBuilderClassName.ToString().Equals("SALFRAME") == true)
                {
                    HandleActivePresentation = intHWnd;
                    return true;
                }
            }

            return false;
        }

        /// <summary>
        /// Execute next slide
        /// </summary>
        public static void NextSlide()
        {
            try
            {
                ApiFunction.PostMessage(HandleActivePresentation, ApiFunction.KEY_DOWN, Keys.PageDown, 0);
            }
            catch (Exception ex)
            {
                Logs.WriteErrorMessage(ex.Message);
            }
        }

        /// <summary>
        /// Execute previous slide
        /// </summary>
        public static void PreviousSlide()
        {
            try
            {
                ApiFunction.PostMessage(HandleActivePresentation, ApiFunction.KEY_DOWN, Keys.PageUp, 0);
            }
            catch (Exception ex)
            {
                Logs.WriteErrorMessage(ex.Message);
            }
        }

        /// <summary>
        /// Execute go to slide(in case full screen)
        /// </summary>
        /// <param name="slideNumber">Slide number</param>
        /// <returns>
        /// true: success
        /// false: fail
        /// </returns>
        public static bool GoToSlide(string slideNumber)
        {
            int intResult;
            bool blnTryParse = int.TryParse(slideNumber, out intResult);
            if (blnTryParse == false)
            {
                Logs.WriteErrorMessage("Invaild input");
                return false;
            }
            else
            {
                try
                {
                    for (int i = 0; i < slideNumber.Length; i++)
                    {
                        Keys k = Keys.D0;
                        int intSingleNo = int.Parse(slideNumber[i].ToString());
                        switch (intSingleNo)
                        {
                            case 0:
                                k = Keys.D0; 
                                break;
                            case 1: 
                                k = Keys.D1;
                                break;
                            case 2: 
                                k = Keys.D2;
                                break;
                            case 3:
                                k = Keys.D3; 
                                break;
                            case 4:
                                k = Keys.D4;
                                break;
                            case 5:
                                k = Keys.D5;
                                break;
                            case 6:
                                k = Keys.D6;
                                break;
                            case 7:
                                k = Keys.D7;
                                break;
                            case 8: 
                                k = Keys.D8;
                                break;
                            case 9:
                                k = Keys.D9;
                                break;
                        }

                        ////lParam cua phim down
                        long lngLParamDown = 0x00000001;

                        ////lParam cua phim up
                        long lngLParamUp = 0xC0000001;
                        ApiFunction.PostMessage(HandleActivePresentation, ApiFunction.KEY_DOWN, k, lngLParamDown);
                        Thread.Sleep(5);
                        ApiFunction.PostMessage(HandleActivePresentation, ApiFunction.KEY_UP, k, lngLParamUp);
                    }

                    ////lParam cua phim Enter khi down
                    long lngLParamEnterDown = 0x001C0001;

                    ////lParam cua phim Enter khi up
                    long lngLParamEnterUp = 0xC01C0001;
                    ApiFunction.PostMessage(HandleActivePresentation, ApiFunction.KEY_DOWN, Keys.Enter, lngLParamEnterDown);
                    Thread.Sleep(5);
                    ApiFunction.PostMessage(HandleActivePresentation, ApiFunction.KEY_UP, Keys.Enter, lngLParamEnterUp);
                }
                catch (Exception ex)
                {
                    Logs.WriteErrorMessage(ex.Message);
                    return false;
                }
            }

            return true;
        }

        /// <summary>
        /// Execute full screen
        /// </summary>
        public static void FullScreen()
        {
            try
            {
                ApiFunction.PostMessage(HandleActivePresentation, ApiFunction.KEY_DOWN, Keys.F5, 0);
            }
            catch (Exception ex)
            {
                Logs.WriteErrorMessage(ex.Message);
            }
        }

        /// <summary>
        /// Execute end full screen
        /// </summary>
        public static void EndFullScreen()
        {
            try
            {
                ApiFunction.PostMessage(HandleActivePresentation, ApiFunction.KEY_DOWN, Keys.Escape, 0);
                DeterminePresentation(FileName);
            }
            catch (Exception ex)
            {
                Logs.WriteErrorMessage(ex.Message);
            }
        }
    }
}